package Robot

type CmdHandler func(*XCommand, *Robot)
type ParamHanlder map[byte]CmdHandler //param,handler
type CmdBegin func(*Robot)

type RobotWork struct {
	BeginHandler CmdBegin //模块开始第一条协议
}

type RobotHandler struct {
	//public
	Robot *Robot
	//private
	handle     map[byte]ParamHanlder //[cmd]param,handler
	workModule map[int32]RobotWork   //moduleid,work
	curwork    int32                 //当前正在执行逻辑编号
	workList   []int32               //工作队列,存储需要顺序执行的模块编号
	isFinish   bool
}

func NewRobotHandler(robot *Robot) *RobotHandler {
	r := &RobotHandler{}
	r.handle = make(map[byte]ParamHanlder)
	r.workModule = make(map[int32]RobotWork)
	r.workList = make([]int32, 0)
	r.isFinish = false
	r.Robot = robot
	return r
}

//SetModuleBegin 设置模块启动函数
func (h *RobotHandler) SetModuleBegin(moduleID int32, begin CmdBegin) {
	h.Robot.RobotLog("SetModuleBegin %s", CmdName(moduleID))
	value, ok := h.workModule[moduleID]
	if !ok {
		h.workModule[moduleID] = RobotWork{BeginHandler: begin}
	} else {
		value.BeginHandler = begin
	}
	h.workList = append(h.workList, moduleID)
	liststr := "任务列表 "
	for i := 0; i < len(h.workList); i++ {
		liststr += CmdName(h.workList[i]) + "|"
	}
	h.Robot.RobotLog(liststr)
}

//RegisterHandle 注册处理
func (h *RobotHandler) RegisterHandle(cmd, param byte, f CmdHandler) {
	_, exist := h.handle[cmd]
	if !exist {
		h.handle[cmd] = make(ParamHanlder)
	}
	h.handle[cmd][param] = f
}

//TriggerHandle 触发逻辑处理
func (h *RobotHandler) TriggerHandle(xcmd *XCommand) {
	cmd := xcmd.Cmd
	param := xcmd.Param

	value, exist := h.handle[cmd]
	if exist {
		f, exist := value[param]
		if exist {
			f(xcmd, h.Robot)
		} else {
			//log
			h.Robot.RobotErr("找不到 cmd:%d param:%d", cmd, param)
		}
	} else {
		//log
		h.Robot.RobotErr("找不到 cmd:%d param:%d", cmd, param)
	}
}

//StartModule 开始执行模块
func (h *RobotHandler) StartModule() {

	if len(h.workList) == 0 {
		h.Robot.RobotLog("所有模块执行结束")
		h.isFinish = true
		return
	}
	//获取第一个需要执行模块
	h.curwork = h.workList[0]
	//剔除
	h.workList = h.workList[1:]
	//获取模块
	value, ok := h.workModule[h.curwork]
	if !ok {
		h.Robot.RobotLog("未知模块 %d", CmdName(h.curwork))
		return
	}
	h.Robot.RobotLog("开始执行 %s", CmdName(h.curwork))
	value.BeginHandler(h.Robot)

}

//FinishModule 某模块逻辑走完
func (h *RobotHandler) FinishModule(moduleID int32) {
	h.Robot.RobotLog("%s 模块执行完成", CmdName(moduleID))
	h.StartModule()
}

//IsFinish 模块是否全部走完
func (h *RobotHandler) IsFinish() bool {
	return h.isFinish
}
